﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web;
using System.Runtime.InteropServices;
using System.Net;

using LMD.Constant;
using LMD.Lib.Interface;
using LMD.Lib.IO;
using LMD.Lib.Controls;

public static class FileHandler
{
    public static string UploadFile(string sxControlId, string sxLOVFieldId, String sxHandlerName,
        HttpPostedFile fileUploaded)
    {
        FileInfo fi = new FileInfo(fileUploaded.FileName);

        // save the file with parametrized name
        // save to database
        // return the database record id, will be used for downloading the file
        String sxRandom = Extensions.RandomDateString();
        
        UploadType tpUpload = GetUploadType(sxHandlerName);
        int iUploadType = (int)tpUpload;

        String sxBasePath = DBQuery.FileUploadTable.GetUploadPath(iUploadType);
        String sxOriginFilename = fi.Name;
        String sxNewFilename = sxRandom + "_" + sxOriginFilename;
        String sxFullFilename = HttpContext.Current.Server.MapPath(
            "~/" + sxBasePath + "/" + sxNewFilename);

        bool IsNeedDeleteButton = true;

        if (sxHandlerName == KFileHandler.UserProfile.PROFILE_PICTURE)
        {
            String sxPath = HttpContext.Current.Server.MapPath("~/" + sxBasePath);
            String sxFileNameWithoutExtension = ICPUser.ID;
            int iMaxPictureSize = KGlobal.PROFILE_PICTURE_MAX_RES;
            
            Image imgResized = ImageLib.ResizeImage(fileUploaded.InputStream, iMaxPictureSize);
            sxOriginFilename = sxNewFilename = ImageLib.ConvertAndSaveImage(imgResized, ImageFormat.Jpeg, sxPath, sxFileNameWithoutExtension);

            sxFullFilename = HttpContext.Current.Server.MapPath("~/" + sxBasePath + "/" + sxNewFilename); 
            IsNeedDeleteButton = false;
        }
        else if (sxHandlerName == KFileHandler.CompanyProfile.COMPANY_LOGO)
        {
            String sxPath = HttpContext.Current.Server.MapPath("~/" + sxBasePath);
            String sxFileNameWithoutExtension = sxControlId;
            int iMaxPictureSize = KGlobal.PROFILE_PICTURE_MAX_RES;

            Image imgResized = ImageLib.ResizeImage(fileUploaded.InputStream, iMaxPictureSize);
            sxOriginFilename = sxNewFilename = ImageLib.ConvertAndSaveImage(imgResized, ImageFormat.Jpeg, sxPath, sxFileNameWithoutExtension);

            sxFullFilename = HttpContext.Current.Server.MapPath("~/" + sxBasePath + "/" + sxNewFilename);
            IsNeedDeleteButton = false;
        }
        else
        {
            fileUploaded.SaveAs(sxFullFilename);
        }
        
        
        String sxFiletype = getMimeFromFile(sxFullFilename);

        int iFileUploadId = 
            DBQuery.FileUploadTable.SaveFileUpload(sxOriginFilename, sxNewFilename, sxFiletype, iUploadType);

        String sxOutput = ": " + CustomControls.Build_FileUploadResult(sxControlId, sxLOVFieldId, sxHandlerName,
            KControl.INPUT_ID, iFileUploadId.ToString(), sxOriginFilename, IsNeedDeleteButton);
        return sxOutput;
    }

    public static int DownloadFileByURL(String sxURL, String sxHandlerName, String sxOriginalFileName)
    {
        UploadType tpUpload = GetUploadType(sxHandlerName);
        String sxRandom = Extensions.RandomDateString();

        int iUploadType = (int)tpUpload;
        String sxBasePath = DBQuery.FileUploadTable.GetUploadPath(iUploadType);
        String sxNewFilename = sxRandom + "_" + sxOriginalFileName;
        String sxFullFilename = HttpContext.Current.Server.MapPath(
            "~/" + sxBasePath + "/" + sxNewFilename);

        WebClient client = new WebClient();
        WebProxy myProxy = new WebProxy();
        myProxy.Address = new Uri(KGlobal.MRTG_PROXY_URI);
        myProxy.BypassProxyOnLocal = true;
        String[] bypassList = {KGlobal.MRTG_URL};
        myProxy.BypassList = bypassList;
        myProxy.Credentials = new NetworkCredential(KGlobal.MRTG_PROXY_USER, 
            KGlobal.MRTG_PROXY_PASSWORD, KGlobal.MRTG_PROXY_DOMAIN);
        client.Proxy = myProxy;
        client.DownloadFile(sxURL, sxFullFilename);

        String sxFiletype = getMimeFromFile(sxFullFilename);

        int iFileUploadId =
            DBQuery.FileUploadTable.SaveFileUpload(sxOriginalFileName, sxNewFilename, sxFiletype, iUploadType);

        return iFileUploadId;
    }

    public static void DownloadFile(String sxFileId)
    {
        int iFileUploadId = int.Parse(sxFileId);

        // arrInfos[0] = ORIGINAL FILENAME
        // arrInfos[1] = PHYSICAL FILENAME
        // arrInfos[2] = PATH
        Object[] arrInfos = DBQuery.FileUploadTable.GetDownloadURL(iFileUploadId);

        if (arrInfos == null)
        {
            HttpContext.Current.Response.Write("FILE IS NOT AVAILABLE OR HAS BEEN DELETED!");
            HttpContext.Current.Response.End();
            return;
        }

        String sxOriginalFilename = Convert.ToString(arrInfos[0]);
        String sxFullFilename = HttpContext.Current.Server.MapPath(
            "~/" + Convert.ToString(arrInfos[2]) + "/" + Convert.ToString(arrInfos[1]));

        IOLib.DownloadFile(sxFullFilename, sxOriginalFilename);
    }

    public static void DeleteFile(String sxFileId)
    {
        int iFileUploadId = int.Parse(sxFileId);
        DBQuery.FileUploadTable.DeleteFile(iFileUploadId);
    }

    public static UploadType GetUploadType(String sxHandlerName)
    {
        // bisa juga ambil dari database kalau mau lebih dinamis
        switch (sxHandlerName)
        {
            case KLOV.CompanyProfile.BASICINFOTYPE: return UploadType.COMPANY_PROFILE;
            case KLOV.CompanyProfile.CONTACTINFOTYPE: return UploadType.CONTACT_DATA;
            case KFileHandler.UFT.INVITATION_ATTACHMENT: return UploadType.EVENT_ATTACHMENT;
            case KFileHandler.UFT.EVENT_ATTACHMENT: return UploadType.EVENT_ATTACHMENT;
            case KFileHandler.UFT.EVENT_LOG: return UploadType.EVENT_LOG;
            case KFileHandler.CV.CUSTOMER_VISIT: return UploadType.CUSTOMER_VISIT;
			case KFileHandler.CC.COURTESY_CALL: return UploadType.COURTESY_CALL;
            case KFileHandler.CD.CONFIGURATION: return UploadType.CONFIGURATION;
            case KFileHandler.CD.DATEK: return UploadType.DATEK;
            case KFileHandler.CD.EVALUASI: return UploadType.EVALUASI;
            case KFileHandler.MRTG.MRTGFILE: return UploadType.MRTG;
            case KFileHandler.UserProfile.PROFILE_PICTURE: return UploadType.USER_PROFILE_PICTURE;
            case KFileHandler.CompanyProfile.COMPANY_LOGO: return UploadType.COMPANY_LOGO;
            case KFileHandler.SLA.SLA_FILE: return UploadType.SLA;
            case KFileHandler.UFT.PRESENTATION: return UploadType.EVENT_PRESENTATION;
            default: return UploadType.GENERAL;
        }
    }

    [DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
    private extern static System.UInt32 FindMimeFromData(
        System.UInt32 pBC,
        [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl,
        [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
        System.UInt32 cbSize,
        [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed,
        System.UInt32 dwMimeFlags,
        out System.UInt32 ppwzMimeOut,
        System.UInt32 dwReserverd
    );

    public static String getMimeFromFile(string filename)
    {
        if (!File.Exists(filename))
            throw new FileNotFoundException(filename + " not found");

        byte[] buffer = new byte[256];
        using (FileStream fs = new FileStream(filename, FileMode.Open))
        {
            if (fs.Length >= 256)
                fs.Read(buffer, 0, 256);
            else
                fs.Read(buffer, 0, (int)fs.Length);
        }
        try
        {
            System.UInt32 mimetype;
            FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
            System.IntPtr mimeTypePtr = new IntPtr(mimetype);
            string mime = Marshal.PtrToStringUni(mimeTypePtr);
            Marshal.FreeCoTaskMem(mimeTypePtr);
            return mime;
        }
        catch (Exception e)
        {
            String ex = e.Message;
            return "unknown/unknown";
        }
    }
}